package cn.matezk.cloud.task;

import cn.hutool.core.util.ObjectUtil;
import cn.matezk.cloud.beans.PaymentNotify;
import cn.matezk.cloud.dao.PaymentOrderDao;
import cn.matezk.cloud.model.PaymentOrder;
import cn.matezk.cloud.service.IPaymentOrderService;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.exception.ServiceException;
import com.wechat.pay.java.service.payments.jsapi.JsapiService;
import com.wechat.pay.java.service.payments.jsapi.model.QueryOrderByOutTradeNoRequest;
import com.wechat.pay.java.service.payments.model.Transaction;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
@Slf4j
public class PaymentOrderQueryTask {
    @Value("${tencent.iot-app-id}")
    private String iotAppId;
    @Value("${payment.merchantId}")
    private String merchantId;
    @Value("${payment.privateKeyPath:}")
    private String privateKeyPath;
    @Value("${payment.merchantSerialNumber:}")
    private String merchantSerialNumber;
    @Value("${payment.apiV3Key:}")
    private String apiV3Key;
    @Autowired
    private PaymentOrderDao paymentOrderDao;

    @Autowired
    private IPaymentOrderService paymentOrderService;

    @Scheduled(cron = "0 * * * * ?")
    public void execute() {
        if (ObjectUtil.isEmpty(apiV3Key))   return;
        try {
            List<PaymentOrder> orders = paymentOrderDao.selectByAppState(iotAppId, "INIT");
            if (ObjectUtil.isEmpty(orders)) return;

            RSAAutoCertificateConfig config = new RSAAutoCertificateConfig.Builder()
                    .merchantId(merchantId)
                    .privateKeyFromPath(privateKeyPath)
                    .merchantSerialNumber(merchantSerialNumber)
                    .apiV3Key(apiV3Key)
                    .build();
            JsapiService appService = new JsapiService.Builder().config(config).build();
            for (PaymentOrder order : orders) {
                QueryOrderByOutTradeNoRequest request = new QueryOrderByOutTradeNoRequest();
                request.setMchid(merchantId);
                request.setOutTradeNo(order.getOrderId());
                Transaction transaction;
                try {
                    transaction = appService.queryOrderByOutTradeNo(request);
                } catch (ServiceException e) {
                    if ("ORDER_NOT_EXIST".equals(e.getErrorCode())) {
                        order.setState("NOTEXIST");
                        order.setStateDesc("订单不存在");
                        paymentOrderDao.updateByPrimaryKeySelective(order);
                    }
                    continue;
                } catch (Exception e) {
                    log.error(e.getMessage());
                    continue;
                }
                PaymentNotify paymentNotify = new PaymentNotify();
                paymentNotify.setAppid(transaction.getAppid());
                paymentNotify.setMchId(transaction.getMchid());
                if (ObjectUtil.isNotNull(transaction.getPayer()))
                    paymentNotify.setOpenid(transaction.getPayer().getOpenid());
                if (ObjectUtil.isNotNull(transaction.getTradeType()))
                    paymentNotify.setTradeType(transaction.getTradeType().name());
                paymentNotify.setBankType(transaction.getBankType());
                paymentNotify.setOutTradeNo(transaction.getOutTradeNo());
                paymentNotify.setTotalFee(transaction.getAmount().getTotal());
                paymentNotify.setResultCode(transaction.getTradeState().name());
                paymentNotify.setErrCode(transaction.getTradeStateDesc());
                paymentNotify.setTimeEnd(transaction.getSuccessTime());
                try {
                    paymentOrderService.notify(paymentNotify);
                } catch (Exception e) {
                    log.error(e.getMessage());
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }
    }
}
